package com.osgix.common.utils.xmlUtil.stc;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.ValidationEventLocator;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.xml.sax.SAXException;

/**
 * @function JAXB 工具类
 * @author Azheng
 * @description: 此工具类使用JAXB将对象转化成xml 或者 将xml文件转化成Object
 * 2009-1-9 上午01:09:28
 */
public abstract class JAXBUtil {

	private static final String DEFAULT_ENCODING = "UTF-8";

	/** 
	 * 将Javabean 对象转化成 xml  
	 * @param jc (JAXBContext)  
	 * @param element (JAXBElement) 
	 * @param xmlPath (String) xml文件路径 
	 * @param encoding 转化的编码 ， 默认为UTF-8 
	 */
	public static void objectToXml(JAXBContext jc, JAXBElement<?> element, final String xmlPath, String encoding) {
		try {
			Marshaller m = jc.createMarshaller();
			//格式化输出  
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
			//编码  
			encoding = encoding == null ? DEFAULT_ENCODING : encoding;
			//打印到控制台  
			m.marshal(element, System.out);
			//设置输出的编码格式  
			m.setProperty("jaxb.encoding", encoding);
			OutputStream out = new FileOutputStream(new File(xmlPath));
			m.marshal(element, out);
			out.flush();
			out.close();
		} catch (JAXBException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/** 
	 * 重载方法， 具体实现看: objectToXml(JAXBContext jc, JAXBElement<?> element, final String xmlPath, String encoding) 
	 * @param jc (JAXBContext) 
	 * @param element (JAXBElement) 
	 * @param xmlPath (String)  xml文件路径 
	 */
	public static void objectToXml(JAXBContext jc, JAXBElement<?> element, final String xmlPath) {
		objectToXml(jc, element, xmlPath, null);
	}

	/** 
	 * 将传入的xml文件，转化成Object 
	 * @param u (Unmarshaller)  
	 * @param xmlPath (String) xml文件路径 
	 * @return Object 
	 */
	public static Object xmlToObject(Unmarshaller u, final String xmlPath) {
		Object obj = null;
		try {
			JAXBElement<?> je = (JAXBElement<?>) u.unmarshal(new FileInputStream(xmlPath));
			obj = je.getValue();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return obj;
	}

	/** 
	 * 验证Schema, 返回一个Unmarshaller对象 
	 * @param jc (JAXBContext) 
	* @param xsdPath (schema文件路径) 
	* @return (Unmarshaller) 
	*/
	public static Unmarshaller validate(JAXBContext jc, String xsdPath) {
		Unmarshaller u = null;
		try {
			u = jc.createUnmarshaller();
			SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
			Schema schema = sf.newSchema(new File(xsdPath));
			u.setSchema(schema);
			u.setEventHandler(new ValidationEventHandler() {

				public boolean handleEvent(ValidationEvent ve) {
					if (ve.getSeverity() == ValidationEvent.ERROR || ve.getSeverity() != ValidationEvent.WARNING) {
						ValidationEventLocator vel = ve.getLocator();
						return false;
					}
					return true;
				}
			});
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return u;
	}
}